package com.gimi.cloud.jimi.client.service.order.impl;

import com.gimi.cloud.jimi.client.service.order.OrderService;
import com.gimi.cloud.jimi.common.enums.CommonEnume;
import com.gimi.cloud.jimi.common.enums.ResponseCodeEnum;
import com.gimi.cloud.jimi.common.exception.MsgException;
import com.gimi.cloud.jimi.common.utils.CommonUtil;
import com.gimi.cloud.jimi.common.utils.RandomUtil;
import com.gimi.cloud.jimi.commonService.common.JmConfigService;
import com.gimi.cloud.jimi.commonService.common.JmUserService;
import com.gimi.cloud.jimi.dao.dao.order.*;
import com.gimi.cloud.jimi.dao.dao.product.ProductDao;
import com.gimi.cloud.jimi.dao.dao.product.ProductSkuDao;
import com.gimi.cloud.jimi.dao.dao.product.ProductStatusDao;
import com.gimi.cloud.jimi.dao.myMapper.core.query.QueryParam;
import com.gimi.cloud.jimi.dto.order.OrderCostDTO;
import com.gimi.cloud.jimi.dto.order.OrderExpressDTO;
import com.gimi.cloud.jimi.dto.order.OrderGoodsDTO;
import com.gimi.cloud.jimi.dto.order.OrderInvoiceDTO;
import com.gimi.cloud.jimi.dto.product.ProductStatusDTO;
import com.gimi.cloud.jimi.entity.order.*;
import com.gimi.cloud.jimi.entity.product.ProductEntity;
import com.gimi.cloud.jimi.entity.product.ProductSkuEntity;
import com.gimi.cloud.jimi.dto.params.OrderParams;

import org.apache.commons.collections.MapUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by shazhiwei on 2018/1/9.
 */
@Service
public class OrderServiceImpl implements  OrderService{
    private final OrderCodeDao orderCodeDao;
    private final OrderDao orderDao;
    private final OrderGoodsDao orderGoodsDao;
    private final OrderExpressDao orderExpressDao;
    private final OrderOperDao orderOperDao;
    private final OrderCostDao orderCostDao;
    private final OrderInvoiceDao orderInvoiceDao;
    private final JmConfigService configService;
    private final JmUserService jmUserService;
    private final ProductSkuDao productSkuDao;
    private final ProductDao productDao;
    private final ProductStatusDao productStatusDao;

    private static Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class);

    public OrderServiceImpl(OrderCodeDao orderCodeDao,OrderDao orderDao,JmConfigService configService,
                            OrderGoodsDao orderGoodsDao,OrderOperDao orderOperDao,OrderExpressDao orderExpressDao,
                            OrderCostDao orderCostDao,OrderInvoiceDao orderInvoiceDao,JmUserService jmUserService,
                            ProductSkuDao productSkuDao,ProductStatusDao productStatusDao,ProductDao productDao){
        this.orderCodeDao = orderCodeDao;
        this.orderDao = orderDao;
        this.configService = configService;
        this.orderGoodsDao = orderGoodsDao;
        this.orderOperDao = orderOperDao;
        this.orderExpressDao = orderExpressDao;
        this.orderCostDao = orderCostDao;
        this.orderInvoiceDao = orderInvoiceDao;
        this.jmUserService = jmUserService;
        this.productSkuDao = productSkuDao;
        this.productStatusDao = productStatusDao;
        this.productDao = productDao;
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRED,rollbackFor = {Exception.class})
    public void addOrder(OrderParams params) {
        String orderCode = getOrderCode();//订单编号
        //保存订单
        Integer oId = saveOrder(params,orderCode);
        params.setOrderCode(orderCode);
        params.setoId(oId);
        //保存订单商品明细
        ProductSkuEntity skuEntity = saveOrderGoods(params);
        //保存订单收货人
        saveOrderExpress(params);
        //保存订单费用明细
        saveOrderCost(params,skuEntity);
        //保存订单发票
        //saveOrderInvoice(params);
        //保存物流信息
        //saveOrderLogistics(params,oId,orderCode);
        //记录订单操作记录
        saveOrderOper(params);

    }

    @Override
    public Map<String,Object> getDataStatus(OrderParams orderParams) {
        Integer userId = orderParams.getUserId();
        return jmUserService.getDataStatus(userId);
    }

    /**
     * 保存订单信息
     */
    private Integer saveOrder(OrderParams orderDTO,String orderCode){
        Integer confirmDay = Integer.parseInt(configService.getValueByKey("confirm_day"));//自动确认收货时间

        OrderEntity orderEntity = new OrderEntity();
        /*
        orderEntity.setUserId(orderDTO.getUserId());
        orderEntity.setOrderCode(orderCode);
        orderEntity.setConfirmDay(confirmDay);//自动确认收货时间
        orderEntity.setActivityId(null);//活动信息(目前没有活动)
        orderEntity.setOrderSource(orderDTO.getOrderSource());//订单来源:app(app来源),wechat(微信),other(其他)
        orderEntity.setOrderType(orderDTO.getOrderType());//订单类型(ordinary普通,lease租赁)
        orderEntity.setPayType(orderDTO.getPayType());//支付方式(lease租赁,stages分期付款,online在线付款,delivery货到付款) 订单类型为租赁支付方式为租赁
        orderEntity.setDistributionType(orderDTO.getDistributionType());//配送方式(express快递,self自取)
        orderEntity.setLogisticsCode(null);//物流单号，配送方式为自取时物流单号为空(添加时物流单号应该是空的)
        orderEntity.setStatus(CommonEnume.OrderStatus.L01.toString());//订单状态(A01已提交待支付,A02支付成功待收货,A03已收货,A09取消;L01已提交审核中,L02审核成功待支付,L03审核拒绝,L04支付成功待收货,,L05已收货,L09取消
        orderEntity.setPayStatus(CommonEnume.PayStatus.nopay.toString());//付款状态(pay已支付,nopay未支付)            订单为租赁类型时支付是支付押金、首期租金
        orderEntity.setLogisticsStatus(CommonEnume.OrderLogisticsStatus.no.toString());//发货状态(yes已发货,no未发货,ing发货中)
        orderEntity.setSendCode(null);//发货单流水号(此时流水号为空)
        */

        orderEntity.setUserId(orderDTO.getUserId());
        orderEntity.setOrderCode(orderCode);
        orderEntity.setConfirmDay(confirmDay);//自动确认收货时间
        orderEntity.setActivityId(null);//活动信息(目前没有活动)
        orderEntity.setOrderSource(CommonEnume.OrderSource.app.name());//订单来源:app(app来源),wechat(微信),other(其他)
        orderEntity.setOrderType(CommonEnume.OrderType.lease.name());//订单类型(ordinary普通,lease租赁)
        orderEntity.setPayType(CommonEnume.PayType.lease.name());//支付方式(lease租赁,stages分期付款,online在线付款,delivery货到付款) 订单类型为租赁支付方式为租赁
        orderEntity.setDistributionType(CommonEnume.DistributionType.express.name());//配送方式(express快递,self自取)
        orderEntity.setLogisticsCode(null);//物流单号，配送方式为自取时物流单号为空(添加时物流单号应该是空的)
        orderEntity.setStatus(CommonEnume.OrderStatus.L01.name());//订单状态(A01已提交待支付,A02支付成功待收货,A03已收货,A09取消;L01已提交审核中,L02审核成功待支付,L03审核拒绝,L04支付成功待收货,,L05已收货,L09取消
        orderEntity.setPayStatus(CommonEnume.PayStatus.nopay.name());//付款状态(pay已支付,nopay未支付)            订单为租赁类型时支付是支付押金、首期租金
        orderEntity.setLogisticsStatus(CommonEnume.OrderLogisticsStatus.no.name());//发货状态(yes已发货,no未发货,ing发货中)
        orderEntity.setSendCode(null);//发货单流水号(此时流水号为空)

        orderDao.insertSelective(orderEntity);
        Integer oId = orderEntity.getoId();
        if(oId == null || oId.equals(0)){
            throw new MsgException(ResponseCodeEnum.INVALID,"保存订单失败");
        }
        return oId;
    }

    /**
     * 保存订单商品信息
     */
    private ProductSkuEntity saveOrderGoods(OrderParams orderDTO){
        //判断商品状态，已下架的商品不能下订单
        OrderGoodsDTO orderGoodsDTO = orderDTO.getOrderGoods();
        //查询商品状态
        ProductStatusDTO statusDTO = productStatusDao.getProductStats(orderGoodsDTO.getProdId());
        //查询商品
        ProductEntity productEntity = productDao.selectByPrimaryKey(orderGoodsDTO.getProdId());
        //查询sku
        ProductSkuEntity skuEntity = productSkuDao.selectByPrimaryKey(orderGoodsDTO.getSkuId());
        if(statusDTO == null){
            throw new MsgException(ResponseCodeEnum.INVALID,String.format("id为%s的商品不存在",orderGoodsDTO.getProdId()));
        }
        if(!statusDTO.getProdStatus().equals(1)){
            throw new MsgException(ResponseCodeEnum.INVALID,"该商品已经下架，订单提交失败");
        }
        OrderGoodsEntity orderGoodsEntity = new OrderGoodsEntity();
        orderGoodsEntity.setoId(orderDTO.getoId());//订单id
        orderGoodsEntity.setOrderCode(orderDTO.getOrderCode());//订单编号
        orderGoodsEntity.setProdId(productEntity.getProdId());//商品id
        orderGoodsEntity.setProdName(productEntity.getProdName());//商品名称
        orderGoodsEntity.setProdBrandName(productEntity.getProdBrandName());//商品品牌名称
        orderGoodsEntity.setProdCode(productEntity.getMerchantProdBarCode());//条形码

        orderGoodsEntity.setSkuId(skuEntity.getSkuId());//单品id
        orderGoodsEntity.setPrice(skuEntity.getSkuPrice());//价格
        //TODO::这里会获取sku的属性组合
        //orderGoodsEntity.setAttribute(skuEntity.get.get());//属性为sku的属性
        orderGoodsEntity.setCost(1);//数量
        orderGoodsEntity.setTotal(orderGoodsEntity.getPrice());//小计
        orderGoodsEntity.setAddTime(new Date());
        orderGoodsDao.insertSelective(orderGoodsEntity);

        return skuEntity;
    }

    /**
     * 保存订单收货信息
     */
    private void saveOrderExpress(OrderParams orderDTO){
        OrderExpressDTO orderExpressDTO = orderDTO.getOrderExpress();
        OrderExpressEntity orderExpressEntity = new OrderExpressEntity();
        orderExpressEntity.setoId(orderDTO.getoId());//订单id
        orderExpressEntity.setOrderCode(orderDTO.getOrderCode());//订单编号
        orderExpressEntity.setName(orderExpressDTO.getName());//收货人姓名
        orderExpressEntity.setMobile(orderExpressDTO.getMobile());//收货人电话
        orderExpressEntity.setAddress(orderExpressDTO.getAddress());//收货人所属省市区(省市区通过空格区隔)
        String detailAddress = CommonUtil.checkParams(orderExpressDTO.getDetailAddress());
        orderExpressEntity.setDetailAddress(detailAddress);//接到地址
        orderExpressEntity.setPostCode(orderExpressDTO.getPostCode());//邮政编码
        orderExpressEntity.setAddTime(new Date());
        orderExpressDao.insertSelective(orderExpressEntity);
    }

    /**
     * 保存订单费用明细
     * 注：费用计算
     * 订单总金额=商品合计+运费-优惠券-活动优惠-折扣金额
     * 首期应付款金额=押金+保险费+租金
     * 实际应付款金额=租金*期数
     * 押金(履约保证金)
     */
    private void saveOrderCost(OrderParams orderDTO,ProductSkuEntity skuEntity){
        OrderCostDTO orderCostDTO = orderDTO.getOrderCost();

        BigDecimal rent = orderCostDTO.getRent();//月租租金
        Integer periods = orderCostDTO.getPeriods();//期数
        BigDecimal deposit = orderCostDTO.getDeposit();//押金
        BigDecimal sign = orderCostDTO.getSign();//签约价
        BigDecimal premium = orderCostDTO.getPremium();//意外保险费

        OrderCostEntity orderCostEntity = new OrderCostEntity();
        orderCostEntity.setoId(orderDTO.getoId());
        orderCostEntity.setOrderCode(orderDTO.getOrderCode());
        orderCostEntity.setRent(rent);//月租租金
        orderCostEntity.setPeriods(periods);//期数
        orderCostEntity.setDeposit(deposit);//押金
        orderCostEntity.setPremium(premium);//保险费
        orderCostEntity.setRentType(CommonEnume.RentType.month.name());//租赁方式(day按天,week按周,month按月,year按年)
        orderCostEntity.setFreightTotal(BigDecimal.ZERO);//运费(包邮)
        orderCostEntity.setCouponTotal(BigDecimal.ZERO);//优惠券(无优惠券)
        orderCostEntity.setActivityTotal(BigDecimal.ZERO);//活动优惠(无活动优惠)
        orderCostEntity.setDiscountTotal(BigDecimal.ZERO);//折扣金额(无折扣)
        orderCostEntity.setSign(sign);//签约价格
        orderCostEntity.setTruePayTotal(orderCostEntity.getRent().multiply(new BigDecimal(periods)));//实际应付款金额为应付款金额的溢价后金额(计算得出)

        orderCostEntity.setTail(orderCostEntity.getTruePayTotal().subtract(orderCostEntity.getRent().multiply(new BigDecimal(periods))));//尾差(由计算得出)
        orderCostEntity.setGoodsTotal(skuEntity.getSkuPrice());//商品合计(由计算得出)
        //订单总额(计算得出)
        orderCostEntity.setOrderTotal(BigDecimal.ZERO.add(orderCostEntity.getFreightTotal())
                                    .subtract(orderCostEntity.getCouponTotal()).subtract(orderCostEntity.getActivityTotal())
                                    .subtract(orderCostEntity.getDiscountTotal())
                                    );
        //应付总额(计算得出)
        orderCostEntity.setPayTotal(BigDecimal.ZERO.add(orderCostEntity.getPremium()).add(orderCostEntity.getRent()));
        orderCostEntity.setAddTime(new Date());
        orderCostDao.insertSelective(orderCostEntity);
    }

    /**
     * 保存订单发票
     */
    private void saveOrderInvoice(OrderParams orderDTO){
        OrderInvoiceDTO orderInvoiceDTO = orderDTO.getOrderInvoice();
        OrderInvoiceEntity orderInvoiceEntity = new OrderInvoiceEntity();
        orderInvoiceEntity.setoId(orderDTO.getoId());//订单id
        orderInvoiceEntity.setOrderCode(orderDTO.getOrderCode());//订单编号
        orderInvoiceEntity.setInvoiceType(orderInvoiceDTO.getInvoiceType());//发票类型
        orderInvoiceEntity.setInvoiceHeadType(orderInvoiceDTO.getInvoiceHeadType());//抬头类型
        orderInvoiceEntity.setInvoiceHead(orderInvoiceDTO.getInvoiceHead());//发票抬头
        orderInvoiceEntity.setTaxCode(orderInvoiceDTO.getTaxCode());//税号
        orderInvoiceEntity.setInvoiceContent("发票内容");//发票内容
        orderInvoiceEntity.setInvoicePersonInfo("发票人信息");//发票人信息
        orderInvoiceDao.insertSelective(orderInvoiceEntity);
    }

    /**
     * 保存物流信息记录,物流信息可以在支付后再初始化
     */
    private void saveOrderLogistics(OrderParams orderDTO,Integer oId,String orderCode){
        /*orderDTO.getlog
        OrderLogisticsEntity orderLogisticsEntity = new OrderLogisticsEntity();
        orderLogisticsEntity.setoId(oId);//订单号
        orderLogisticsEntity.setProdId("");//商品id
        orderLogisticsEntity.setOrderCode(orderCode);//订单编号
        orderLogisticsEntity.setLogisticsCompany("");//物流公司名称
        orderLogisticsEntity.setLogisticsStatus();*/
    }

    /**
     * 保存操作记录
     */
    private void saveOrderOper(OrderParams orderDTO){
        OrderOperEntity operEntity = new OrderOperEntity();
        operEntity.setoId(orderDTO.getoId());//订单id
        operEntity.setOrderCode(orderDTO.getOrderCode());//订单编号
        operEntity.setStatus(CommonEnume.OrderStatus.L01.name());//订单状态
        operEntity.setPayStatus(CommonEnume.PayStatus.nopay.name());//支付状态
        operEntity.setLogisticsStatus(CommonEnume.OrderLogisticsStatus.no.name());//发货状态
        orderOperDao.insertSelective(operEntity);
    }
    /**
     * 订单编号,规则:14位年月日时分秒+4位随机码+7位自增id；7位自增id通过建立一个空表，
     * 使用空表的自增id作为当前值，不够7位的通过前端补0的方式完成'
     * @return 订单号
     */
    public String getOrderCode(){
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");//设置日期格式
        String first = df.format(new Date());
        String second = RandomUtil.getRandomNumString(4);
        OrderCodeEntity entity = new OrderCodeEntity();
        orderCodeDao.insert(entity);
        String third = entity.getId() + "";
        if(third.length() >= 7){
            third = third.substring(0,7);
        }else{
            StringBuilder pre = new StringBuilder();
            for(int i = 0;i< 7 - third.length();i++){
                pre.append("0");
            }
            third = pre.toString() + third;
        }
        logger.error("===>订单号：" + first + "   "+second + "    "+third);
        return first+second+third;
    }
    
    /**app用户订单列表***/
	@Override
	public List<Map> getOrderList(OrderParams orderParams) throws Exception {
        Integer userId = orderParams.getUserId();
        logger.info(String.format("===>开始获取用户%s的订单列表",userId));
        List<Map> list = orderDao.getListByUserId(userId);
        if(list != null && list.size() > 0){
            logger.info(String.format("===>获取订单userId为%d的订单数据共有%d条",userId,list.size()));
            StringBuilder skuIds = new StringBuilder();
            for(Map map : list){
                map.put("modelValueList",new ArrayList<>());//只作初始化
                String status = MapUtils.getString(map,"status");
                map.put("status",CommonEnume.ConvertEnumMap(CommonEnume.OrderStatus.class).get(status));
                skuIds.append("'").append(MapUtils.getString(map,"sku_id")).append("'").append(",");
            }
            System.out.println(skuIds.toString());
            if(skuIds.length() > 0){
                skuIds.delete(skuIds.length()-1,skuIds.length());
            }
            logger.info("===>skuIds : " + skuIds);
            QueryParam queryParam = new QueryParam();
            String sql = "SELECT sku_id,model_value FROM ec_prod_sku sku LEFT JOIN ec_prod_cat_model_value cm ON FIND_IN_SET(cm_id,sku.sku_value) WHERE sku.sku_id IN (" + skuIds.toString() + ")";
            List<Map> data = productSkuDao.getModelValueBySkuIds2(sql);
            //List<Map> data = productSkuDao.getModelValueBySkuIds(skuIds.toString());
            if(data != null && data.size() > 0){
                logger.info(String.format("===>获取订单userId为%d的skuModel数据共有%d条",userId,data.size()));
                for(Map outer : list){
                    String outerSkuId = MapUtils.getString(outer,"sku_id");
                    List<String> modelValueList = new ArrayList<>();
                    for(Map inner : data){
                        String innerSkuId = MapUtils.getString(inner,"sku_id");
                        if(outerSkuId.equals(innerSkuId)){
                            modelValueList.add(MapUtils.getString(inner,"model_value"));
                        }
                    }
                    outer.put("modelValueList",modelValueList);
                }
            }else{
                logger.info(String.format("===>没有用户%d的skuModel",userId));
            }
        }else{
            logger.info(String.format("===>没有用户%d的订单",userId));
        }
	    return list;
	}

}
